<?php

/**
 * Menashop
 *
 * LICENSE
 *
 * This source file is subject to the license that is bundled
 * with this project in the file LICENSE.txt
 *
 * @category   Menashop
 * @package    Menashop_Prices
 * @subpackage Importer
 * @copyright  Copyright (c) 2011 Menashop UA Inc. (http://www.menashop.com.ua)
 * @license    LICENSE.txt
 * @version    1.0.0
 * @since      File available since Release 1.0.0
 */

/**
 * The pricelist importer
 * 
 * @category   Menashop
 * @package    Menashop_Prices
 * @subpackage Importer
 * @copyright  Copyright (c) 2011 Menashop UA Inc. (http://www.menashop.com.ua)
 * @license    LICENSE.txt
 */
class Menashop_Prices_Importer
{

    /**
     * The logger
     * @var Zend_Log
     */
    protected $_logger;

    /**
     * The config
     * @var Zend_Config
     */
    protected $_config;

    /**
     * The data model for distributor pricelist
     * @var Admin_Model_DistributorPricelist
     */
    protected $_distributorPricelistModel;

    /**
     * The model for a manufacturer
     * @var Admin_Model_Manufacturer
     */
    protected $_manufacturerModel;

    /**
     * The data model for provider product
     * @var Admin_Model_ProviderProduct
     */
    protected $_providerProductModel;

    /**
     * The data model for distributor product
     * @var Admin_Model_DistributorProduct
     */
    protected $_distributorProductModel;

    /**
     * The data model for product
     * @var Admin_Model_Product
     */
    protected $_productModel;

    /**
     * The data model for category
     * @var Admin_Model_Category
     */
    protected $_categoryModel;

    /**
     * The counter for prices
     * @var integer 
     */
    protected $_totalProducts = 0;

    /**
     * The counter for inserted prices
     * @var integer 
     */
    protected $_totalProductsInserted = 0;

    /**
     * The counter for updated prices
     * @var integer 
     */
    protected $_totalProductsUpdated = 0;

    /**
     * The counter for skipped prices
     * @var integer
     */
    protected $_totalProductsMatched = 0;

    /**
     * Initialize the price importer for Ugcontract 
     */
    public function __construct()
    {
        $this->_distributorPricelistModel = new Admin_Model_DistributorPricelist();
        $this->_manufacturerModel = new Admin_Model_Manufacturer();
        $this->_providerProductModel = new Admin_Model_ProviderProduct();
        $this->_distributorProductModel = new Admin_Model_DistributorProduct();
        $this->_productModel = new Admin_Model_Product();
        $this->_categoryModel = new Admin_Model_Category();
        $this->_logger = Zend_Registry::get('log');
        $this->_config = Zend_Registry::get('config')->import->pricelist;
    }

    /**
     * Get the report about an import of prices
     * @return string 
     */
    protected function _getImportReport()
    {
        $report = "$this->_totalProducts prices in XLS,";
        $report .= " $this->_totalProductsInserted inserted,";
        $report .= " $this->_totalProductsUpdated updated";
        $report .= " $this->_totalProductsMatched matched";
        return $report;
    }

    /**
     * Import prices
     */
    public function importPrices()
    {
        $startTime = microtime(true);
        $this->_logger->info(__METHOD__ . " started");
        $priceLists = $this->_distributorPricelistModel->getAll();
        foreach ($priceLists as $priceList) {
            if ($priceList->format == 'xls') {

                // Get manufacuturer names and Ids
                $manufacturerNames = $this->_manufacturerModel->fetchPairsNameAndContentId();
                $manufacturerIds = $this->_manufacturerModel->fetchPairsContentIdAndId();
                $categoryIds = $this->_categoryModel->fetchPairsContentIdAndId();

                // Initialize a reader for Excel file
                $data = new Spreadsheet_Excel_Reader();
                $data->setOutputEncoding('UTF8');
                $data->read($this->_config->downloadPath . $priceList->local_file);
                error_reporting(E_ALL ^ E_NOTICE);

                // Parse pricelist
                for ($i = $priceList->header_rows + 1; $i <= $data->sheets[0]['numRows']; $i++) {
                    $distributorProduct = array();

                    // Process price
                    $distributorProduct['price'] = $data->sheets[0]['cells'][$i][$priceList->price_column] * $priceList->currency_rate;

                    // Check product name
                    $distributorProduct['name'] = $data->sheets[0]['cells'][$i][$priceList->name_column];

                    $distributorProduct['name'] = $productName = preg_replace('/\s[а-яА-Я]/', '', $distributorProduct['name']);

                    // Process product name
                    $productName = preg_replace('/^.+\s[A-Z&-]{2,}\s(.+)$/', '$1', $distributorProduct['name']);

                    // Process manufacturer name
                    $manufacturerName = preg_replace('/^.+\s([A-Z&-]{2,})\s.+$/', '$1', $distributorProduct['name']);


                    // Check manufacturer
                    if (isset($manufacturerNames[strtoupper($manufacturerName)])) {
                        $manufacturerContentId = $manufacturerNames[strtoupper($manufacturerName)];

                        // Find product in content list
                        $providerProduct = $this->_providerProductModel->getBySupplierIdAndName($manufacturerContentId, $productName);
                        if ($providerProduct) {

                            // Find product by content id
                            $productId = $this->_productModel->findIdByContentId($providerProduct->product_id);

                            // Insert new product if necessary
                            if (!$productId) {
                                $product = array();
                                $product['content_id'] = $providerProduct->product_id;
                                $product['mpn'] = $providerProduct->prod_id;
                                $product['name'] = $providerProduct->model_name;
                                $product['manufacturer_id'] = $manufacturerIds[$providerProduct->supplier_id];
                                $product['category_id'] = $categoryIds[$providerProduct->catid];
                                $productId = $this->_productModel->save($product);
                            }
                            $distributorProduct['product_id'] = $productId;
                            $this->_totalProductsMatched++;
                        } else {
                            echo $manufacturerName . ' ' . $productName . "\n";
                        }
                    }
                    // Find distributor product
                    $distributorProductId = $this->_distributorProductModel->findIdByNameAndDistributorId($distributorProduct['name'], $priceList->distributor_id);
                    if ($distributorProductId) {
                        // Update distributor product
                        $distributorProduct['id'] = $distributorProductId;
                        $this->_totalProductsUpdated++;
                    } else {
                        // Insert new distributor product
                        $distributorProduct['distributor_id'] = $priceList->distributor_id;
                        $this->_totalProductsInserted++;
                    }
                    $this->_distributorProductModel->save($distributorProduct);
                    $this->_totalProducts++;
                }
                $this->_logger->debug(__METHOD__ . ' ' . $this->_getImportReport());
            }
        }
        $this->_logger->debug(__METHOD__ . " started update of categories after prices import");
        $categoryModel = new Admin_Model_Category();
        $categoryModel->updateAllAfterImport();
        $totalTime = round(microtime(true) - $startTime, 1);
        $this->_logger->info(__METHOD__ . " spent $totalTime s");
    }

    /**
     * Update shop prices
     */
    public function updatePrices()
    {
        $startTime = microtime(true);
        $this->_logger->info(__METHOD__ . " started");
        $minPrices = $this->_distributorProductModel->getMinPrices();
        $priceRuleModel = new Admin_Model_PriceRule();
        $priceRules = $priceRuleModel->getAll();
        foreach ($priceRules as $priceRule) {
            $productIds = $this->_productModel->getIdsForPriceRule($priceRule->product_id, $priceRule->category_id, $priceRule->manufacturer_id);
            foreach ($productIds as $productId) {
                $product = array();
                $product['id'] = $productId;
                if ($priceRule->price) {
                    $product['price'] = $priceRule->price;
                } else {
                    $product['price'] = $minPrices[$productId] * (1 + $priceRule->markup / 100);
                }
                $this->_productModel->save($product);
            }
        }
        $totalTime = round(microtime(true) - $startTime, 1);
        $this->_logger->info(__METHOD__ . " spent $totalTime s");
    }

}

